package james.edu.gui;
import james.edu.db.FlashCardDao;
import james.edu.db.HSQLFlashCardDaoImpl;
import james.edu.to.FlashCardTO;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class FlashCardFrame extends JFrame{

	protected ImagePanel imgPanel = new ImagePanel();
	protected JPanel wordPanel = new JPanel();
	protected JPanel ctrPanel = new JPanel();
	protected JPanel optionsPanel = new JPanel();
	protected JPanel topPanel = new JPanel();
	protected JPanel leftPanel = new JPanel();
	protected JPanel bottomPanel = new JPanel();
	protected JButton prevBtn = new JButton("previous");
	protected JButton nextBtn = new JButton("next");
	protected JButton addBtn = new JButton("add word");
	protected JButton delBtn = new JButton("delete this word");
	protected JButton confirmAddBtn = new JButton("add");
	protected JButton cancelAddBtn = new JButton("cancel");
	protected JTextField addWordBox = new JTextField();
	protected JTextField addImageBox = new JTextField();
	protected JDialog wind = null;
	
	protected List list = null;
	protected int numberOfCards = 0;
	protected int cardIndex = 0;
	protected String imageFile = null;
	protected JTextArea text = new JTextArea();
	protected JCheckBox showPictureChBx = new JCheckBox("show picture");
	protected JCheckBox markCorrectChBx = new JCheckBox("mark correct");
	protected boolean useDb;
	protected ApplicationContext ac;
	protected FlashCardDao  flashCardDao;
	protected BasicDataSource hsqlDataSource;
	
	public FlashCardFrame() {
		super();
		setUseDb(true);
		
        ac = new ClassPathXmlApplicationContext("spring/db.xml");
        
        flashCardDao = (HSQLFlashCardDaoImpl) 
            ac.getBean("hsqlFlashCardDao");
        
        hsqlDataSource = (BasicDataSource) 
        ac.getBean("hsqlDataSource"); 
        
		init();		
	}
	
	public FlashCardFrame(String imageFile) {
		super();
		setImageFile(imageFile);
		init();		
	}
	
	private void loadImageandWord() {	
		
		if(getNumberOfCards() == 0) {
			imgPanel.setVisible(false);
			wordPanel.setVisible(false);
			this.repaint();
			return;
		}
		else {
			imgPanel.setVisible(true);
			wordPanel.setVisible(true);
			this.repaint();
		}
				
		FlashCardTO cardInfo = (FlashCardTO) list.get(getCardIndex());
		ImageIcon image = cardInfo.getImage();
		
		imgPanel.setImage(image.getImage());
		
		text.setText(image.getDescription());		
		
		markCorrectChBx.setSelected(cardInfo.isCorrect());
		
		showPictureChBx.setSelected(cardInfo.isShowPicture());
		imgPanel.setVisible(cardInfo.isShowPicture());
		
		if(cardInfo.isCorrect()) {
			text.setForeground(Color.GREEN);
		}
		else {
			text.setForeground(Color.BLACK);
		}
		
		imgPanel.validate();
		this.validate();
		this.repaint();

	}
	
	private void init() {	
		
		if(isUseDb()) {
			this.setTitle("Flash Cards (db: " + 
					this.hsqlDataSource.getUrl() +")");
			leftPanel.setLayout(new GridLayout(12,1));
			leftPanel.add(new JPanel());
			leftPanel.add(new JPanel());
			leftPanel.add(new JPanel());
			leftPanel.add(new JPanel());
            leftPanel.add(addBtn);
			addBtn.addActionListener(new AddWordListener());
			confirmAddBtn.addActionListener(new AddWordListener());
			cancelAddBtn.addActionListener(new AddWordListener());
			leftPanel.add(new JPanel());
			leftPanel.add(new JPanel());
            leftPanel.add(delBtn);
			delBtn.addActionListener(new DeleteListener(this));
			leftPanel.add(new JPanel());
			leftPanel.add(new JPanel());
			leftPanel.add(new JPanel());
			leftPanel.add(new JPanel());
		}
		else {
			this.setTitle("Flash Cards (input file: " + this.getImageFile() +")");			
		}
		
		setSize(800,500);
		
		topPanel.add(prevBtn);
		topPanel.add(nextBtn);
		prevBtn.setBorder(BorderFactory.createRaisedBevelBorder());
		nextBtn.setBorder(BorderFactory.createRaisedBevelBorder());
		prevBtn.setEnabled(false);
		
		ButtonClickListener listener = new ButtonClickListener();
		nextBtn.addActionListener(listener);
		prevBtn.addActionListener(listener);
		
		CheckBoxListener radioListener = new CheckBoxListener();
		showPictureChBx.addItemListener(radioListener);
		markCorrectChBx.addItemListener(radioListener);
		
		wordPanel.setBackground(Color.WHITE);
//		wordPanel.setSize(200,500);
//		wordPanel.setPreferredSize(new Dimension(200,500));
//		wordPanel.setMinimumSize(new Dimension(200,500));
		text.setBackground(Color.WHITE);
		text.setFont(new Font(null, Font.BOLD, 30));
		wordPanel.add(text);
		
		if(isUseDb()) {
			list = flashCardDao.getAllActive();
		}
		else {
			list = Utils.loadImages(imageFile);
		}
		
		setNumberOfCards(list.size());
		
		if ( (list ==null) || (list.size() == 0) ) {
			System.out.println("image list is empty");
			if(!isUseDb()) {
			    System.exit(-1);
			}
		}				
		
		loadImageandWord();
		
		if(getNumberOfCards() > 1) {
			nextBtn.setEnabled(true);
		}
		else {
			nextBtn.setEnabled(false);
		}
		
		ctrPanel.setLayout(new GridLayout(1,2));
		ctrPanel.add(wordPanel);
		ctrPanel.add(imgPanel);
		
		getContentPane().add(ctrPanel, BorderLayout.CENTER);
		//getContentPane().add(imgPanel, BorderLayout.CENTER);
		//getContentPane().add(wordPanel,BorderLayout.WEST);
		getContentPane().add(topPanel,BorderLayout.NORTH);
		
		optionsPanel.setLayout(new GridLayout(3,1));
		optionsPanel.add(showPictureChBx);
		optionsPanel.add(markCorrectChBx);
		getContentPane().add(optionsPanel, BorderLayout.EAST);
		getContentPane().add(leftPanel, BorderLayout.WEST);
		getContentPane().add(bottomPanel, BorderLayout.SOUTH);
		
		validate();
		setVisible(true);
		
		this.addWindowListener(new FlashCardWindowListener());
	}
	
	class CheckBoxListener implements ItemListener {		
		public void itemStateChanged(ItemEvent e) {
			
			FlashCardTO card = getCurrentCard();

			if(e.getSource() == showPictureChBx) {
			    JCheckBox cb = (JCheckBox) e.getSource();			    
				card.setShowPicture(cb.isSelected());					
			}
			else if(e.getSource() == markCorrectChBx) {
				JCheckBox cb = (JCheckBox) e.getSource();
				card.setCorrect(cb.isSelected());
			}

            if(isUseDb()) {
            	flashCardDao.update(card);
			}
			
			loadImageandWord();
			
		}
	}
	
	class FlashCardWindowListener extends WindowAdapter {
		
		public void windowClosing(WindowEvent we) {
        	System.out.println("closing flash card program");
        	System.exit(-1);
        }
		
	}
	
	class DeleteListener implements ActionListener {
		
		JFrame frame;
		
		public DeleteListener (JFrame f) {
			frame = f;
		}
		public void actionPerformed(ActionEvent e) {
			int n = JOptionPane.showConfirmDialog(
				    frame,
				    "Are you sure you want to delete this word?",
				    "Deleting Word",
				    JOptionPane.YES_NO_OPTION);
			
			
			if(n == JOptionPane.YES_OPTION) {
				FlashCardTO card = getCurrentCard(); 
				list.remove(card);
				flashCardDao.archive(card);
				if(getCardIndex() == getNumberOfCards() - 1) {
					setCardIndex(getCardIndex() - 1);
				}
				
				setNumberOfCards(getNumberOfCards() - 1);
				
				setButtons();
				loadImageandWord();
			}
		}

	}
	
	protected FlashCardTO getCurrentCard() {
		return (FlashCardTO) list.get(getCardIndex());
	}
	
	protected void setButtons() {
		if(getNumberOfCards() == 0) {
			prevBtn.setEnabled(false);
			nextBtn.setEnabled(false);
			return;
		}
		
		if(getCardIndex() == 0) {
            prevBtn.setEnabled(false);					
		}
		else {
			prevBtn.setEnabled(true);
		}
		if(getCardIndex() == (getNumberOfCards() - 1)) {
            nextBtn.setEnabled(false);					
		}
		else {
			nextBtn.setEnabled(true);
		}
	}
	
	class ButtonClickListener implements ActionListener {		
		public void actionPerformed(ActionEvent e) {
			if(e.getSource() == prevBtn) {
				setCardIndex(getCardIndex() - 1);				
			}
			else if(e.getSource() == nextBtn) {
				setCardIndex(getCardIndex() + 1);				
			}		
			
			setButtons();
			
			loadImageandWord();
			
		}
	}

	class AddWordListener implements ActionListener {		
		public void actionPerformed(ActionEvent e) {			
			
			if(e.getSource() == addBtn) {
				wind = new JDialog();
				JPanel completePanel = new JPanel();
				completePanel.setLayout(new GridLayout(2,1));
				JPanel boxPanels = new JPanel();
				boxPanels.setLayout(new GridLayout(4,1));
				JPanel btnPanels = new JPanel();
				wind.getContentPane().add(completePanel, BorderLayout.CENTER);
				wind.getContentPane().add(new JPanel(), BorderLayout.WEST);
				wind.getContentPane().add(new JPanel(), BorderLayout.EAST);
				boxPanels.add(new JLabel("word:"));
				boxPanels.add(addWordBox);
				boxPanels.add(new JLabel("location (url or filename):"));
				boxPanels.add(addImageBox);
				completePanel.add(boxPanels);
				completePanel.add(btnPanels);
				btnPanels.add(confirmAddBtn);
				btnPanels.add(cancelAddBtn);	
				
				wind.setSize(200,200);
				wind.setVisible(true);
				wind.validate();
								
			}
			else if(e.getSource() == confirmAddBtn) {
				FlashCardTO newCard = new FlashCardTO();
				newCard.setImageLocation(addImageBox.getText());
				newCard.setDescription(addWordBox.getText());
				flashCardDao.save(newCard);
				list.add(newCard);
				
				setNumberOfCards(getNumberOfCards() + 1);
				setCardIndex(list.indexOf(newCard));
				
				if(wind != null) {
                    wind.setVisible(false);
				}
                wind = null;
                
                loadImageandWord();
			}		
			else if(e.getSource() == cancelAddBtn) {
				if(wind != null) {
                    wind.setVisible(false);
				}
                wind = null;				
			}
			
			setButtons();
			
			loadImageandWord();
			
		}
	}

	public int getCardIndex() {
		return cardIndex;
	}

	public void setCardIndex(int cardIndex) {
		this.cardIndex = cardIndex;
	}

	public JPanel getCtrPanel() {
		return ctrPanel;
	}

	public void setCtrPanel(JPanel ctrPanel) {
		this.ctrPanel = ctrPanel;
	}

	public ImagePanel getImgPanel() {
		return imgPanel;
	}

	public void setImgPanel(ImagePanel imgPanel) {
		this.imgPanel = imgPanel;
	}

	public List getList() {
		return list;
	}

	public void setList(List list) {
		this.list = list;
	}

	public JButton getNextBtn() {
		return nextBtn;
	}

	public void setNextBtn(JButton nextBtn) {
		this.nextBtn = nextBtn;
	}

	public int getNumberOfCards() {
		return numberOfCards;
	}

	public void setNumberOfCards(int numberOfCards) {
		this.numberOfCards = numberOfCards;
	}

	public JButton getPrevBtn() {
		return prevBtn;
	}

	public void setPrevBtn(JButton prevBtn) {
		this.prevBtn = prevBtn;
	}

	public JPanel getTopPanel() {
		return topPanel;
	}

	public void setTopPanel(JPanel topPanel) {
		this.topPanel = topPanel;
	}

	public JPanel getWordPanel() {
		return wordPanel;
	}

	public void setWordPanel(JPanel wordPanel) {
		this.wordPanel = wordPanel;
	}

	public String getImageFile() {
		return imageFile;
	}

	public void setImageFile(String imageFile) {
		this.imageFile = imageFile;
	}

	public JTextArea getLabel() {
		return text;
	}

	public void setLabel(JTextArea label) {
		this.text = label;
	}
	
	public static void main(String args []) {
		JFrame FlashCardFrame = new FlashCardFrame("c:/temp/flashCards.txt");
	}

	public JCheckBox getMarkCorrectChBx() {
		return markCorrectChBx;
	}

	public void setMarkCorrectChBx(JCheckBox markCorrectChBx) {
		this.markCorrectChBx = markCorrectChBx;
	}

	public JCheckBox getShowPictureChBx() {
		return showPictureChBx;
	}

	public void setShowPictureChBx(JCheckBox showPictureChBx) {
		this.showPictureChBx = showPictureChBx;
	}

	public JPanel getOptionsPanel() {
		return optionsPanel;
	}

	public void setOptionsPanel(JPanel optionsPanel) {
		this.optionsPanel = optionsPanel;
	}

	public JPanel getBottomPanel() {
		return bottomPanel;
	}

	public void setBottomPanel(JPanel bottomPanel) {
		this.bottomPanel = bottomPanel;
	}

	public JPanel getLeftPanel() {
		return leftPanel;
	}

	public void setLeftPanel(JPanel leftPanel) {
		this.leftPanel = leftPanel;
	}

	public JTextArea getText() {
		return text;
	}

	public void setText(JTextArea text) {
		this.text = text;
	}

	public boolean isUseDb() {
		return useDb;
	}

	public void setUseDb(boolean useDb) {
		this.useDb = useDb;
	}
	
}
